查看原文
其他

某刷步软件接口分析

pianpu 看雪学院 2021-03-07

本文为看雪论坛优秀文章
看雪论坛作者ID:pianpu


首先和大家道歉先,由于Mac不会装jadx-gui,分析的时候显示效果有点差,请大家见谅一下。小白第一次发帖,大佬请勿喷!

无聊的时候看到一款刷步数的软件,可以刷微信支付宝QQ步数。挺强哈,那我就抓包看看。发现抓包失败了。


那么软件肯定禁止抓包了,所以我们另谋出路吧。

先看看软件。发现软件被加固了,需要脱壳下,这里就不演示脱壳过程了。
(论坛上有大佬分享的脱壳机,大家可以去尝试下,如fdex2反射大师)

脱壳完,通过分析com包下的e4aruntime,发现这是一款E4A编写的安卓软件。


原谅我Mac不会装jadx-gui,暂时用mt看下代码吧。

通过清单文件,我们发现在代码存储在jshare.steps下,所以我们看下主窗口的源代码:







通过代码分析,我们可以很清晰的知道,确实调用了方法,禁止了抓包。

而且还有sign值,且通过Apputils下的encode方法进行加密sign值后提交到服务器。

而sign值是通过apputils类下的decode方法加密的传入的值为 jin.encode()+账号+密码+步数+ jin.encode(),加密的代码在so层。我也不会看so层呀。(继续看后面的操作)

因为java层有传输encode(),我们可以知道这个值。

而请求地址也是加密的。而且调用了其他类进行解密。我们单单分析源代码页可以解密出来。

但是,今天我讲一个另类的解密。我们可以这样。因为E4A是一个封装化的软件。所有代码都是封装在e4aruntime中。

所以我们只需要通过Xposed Hook神器,对这些命令进行hook,就可以知道参数和返回值啦。

但是还有一个点,软件加固了,是腾讯的加固。我们需要hook到这个类加载器才可以hook这些方法成功。

这里告诉大家一个技巧,如何快速找类加载器的方法,通常类加载器的方法下有system.loadlibrary命令,因为加固后都是调用so文件的。

现在最新的腾讯加固类加载器在com.stub.StubApp下的attachBaseContext方法。

我们通过上图,可以得知这些命令分别是开始取网页源码,开始发送网络数据4 Authcode加密我们找下方法。



那么我们hook这个com.e4a.runtime.加密操作和apputils的加解密方法。

代码给大家贴一下。

//hook e4a 发送网络数据4 XposedBridge.hookAllMethods(XposedHelpers.findClass("com.e4a.runtime.网络操作", classLoader), "发送网络数据4", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String data = (String) param.args[0]; String key = (String) param.args[1]; Log.d("pianpu", "=========================发送网络请求参数========================" ); Log.d("pianpu", "data:" +data); Log.d("pianpu", "key:" +key); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "url:" +data + "\n" + "data:" +key; tools.writefilebefore(path,data2,"发送网络数据4"); } protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String result = ""+ (String) param.getResult(); Log.d("pianpu", "result:" +result); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "result:" +result ; tools.writefileafter(path,data2,"发送网络数据4"); } }); //hook e4a 取网页源码 XposedBridge.hookAllMethods(XposedHelpers.findClass("com.e4a.runtime.网络操作", classLoader), "取网页源码", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String data = (String) param.args[0]; String key = (String) param.args[1]; Log.d("pianpu", "=========================取网页源码========================" ); Log.d("pianpu", "data:" +data); Log.d("pianpu", "key:" +key); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "url:" +data + "\n" + "data:" +key; tools.writefilebefore(path,data2,"取网页源码"); } protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String result = ""+ (String) param.getResult(); Log.d("pianpu", "result:" +result); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "result:" +result ; tools.writefileafter(path,data2,"取网页源码"); } });

//e4a Authcode 加密获得的数据 XposedBridge.hookAllMethods(XposedHelpers.findClass("com.e4a.runtime.加密操作", classLoader), "Authcode加密", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String data = (String) param.args[0]; String key = (String) param.args[1]; Log.d("pianpu", "|=========================Authcode加密========================|" ); Log.d("pianpu", "data:" +data); Log.d("pianpu", "key:" +key); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "data:" +data + "\n" + "key:" +key; tools.writefilebefore(path,data2,"Authcode加密"); } protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String result = ""+ (String) param.getResult(); Log.d("pianpu", "result:" +result); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "result:" +result ; tools.writefileafter(path,data2,"Authcode加密"); } }); //e4a Authcode 解密获得的数据 XposedBridge.hookAllMethods(XposedHelpers.findClass("com.e4a.runtime.加密操作", classLoader), "Authcode解密", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String data = (String) param.args[0]; String key = (String) param.args[1]; Log.d("pianpu", "|=========================Authcode解密========================|" ); Log.d("pianpu", "data:" +data); Log.d("pianpu", "key:" +key); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "data:" +data + "\n" + "key:" +key; tools.writefilebefore(path,data2,"Authcode解密"); } protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { String result = ""+ (String) param.getResult(); Log.d("pianpu", "result:" +result); String path = "/sdcard/PP_Hook/"+ packagename + "/Decrypt.txt"; String data2 = "result:" +result ; tools.writefileafter(path,data2,"Authcode解密"); } });

我们只需要hook这4个就行。其中无论他咋加密,我们都不需要去管他。只需要看过程和加密类型方法即可。

运行后,我们可以看到已经把核心代码hook下来且输出到本地文件了。




因为我不会so层分析,所以暂时对这个sign值没方法获取加密方法。(最近正在学习frida hook so层的)。

据此,sign值,我确实不知道咋加密的,但是看上去像是md5加密。刚好测试了一下,这个md5没有另外的加盐处理。嘻嘻

明文的sign =Jni.encode()+账号+密码+步数+Jni.encode(),例子就是  jshare6661234561234568888jshare666。

其中jshare666 是在java层传输,我们可以知道。其中的是账号密码步数。所以我们md5加密一下看看,与这个sign值一样不。



测试了一下,sign值是相同的,被我猜中了。属实是运气好,这个作者也不在so层再次加盐了,以至于被我们猜中。

那么这些提交的网址数据sign我们都知道了,且加密类型密码我们都知道。就可以调用啦。

可以看出,提交后返回的密文,进行了解密,再次返回一个链接,我们访问看看。



因为我们是乱写的参数,所以自然登陆失败。




可以看到,进行一些列网页请求后返回提示给App。至此分析完毕。小白首次发贴,大佬请勿喷!有正在研究so层的,可以一起交流学习下。



- End -





看雪ID:pianpu

https://bbs.pediy.com/user-783437.htm 

*本文由看雪论坛 pianpu 原创,转载请注明来自看雪社区。


推荐文章++++

为了理解反汇编引擎而写的X86/X64反汇编引擎

捆绑包驱动锁首病毒分析

**游戏逆向分析笔记

对宝马车载apps协议的逆向分析研究

x86_64架构下的函数调用及栈帧原理

好书推荐






公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



“阅读原文”一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存